﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Globalization;
using System.Reflection;  // Para el GregorianCalendar.
using Dominio;
using Log4Net;

namespace HotelGUI
{
    public partial class GUIVentanaPrincipal : Form
    {
        private Assembly     assm;
        private List<string> listaPaths;
        private List<string> direccion;
        ISistema sistema;
        private int usuario;

        private int CANT_SEGS=0;
        private int SEGS_REFRESH_RESERVAS=300; // 5 min

        public GUIVentanaPrincipal()
        {
            InitializeComponent();
            sistema = Sistema.getInstance();
            CargarPlugIns();
        }

        public GUIVentanaPrincipal(String User, Form owner)
        {
            InitializeComponent();
            this.Owner = owner;
            sistema = Dominio.Fabrica.getSistema();
            tslblUsuario.Text = User;
            usuario = sistema.obtenerIdUsuario(User);


        }

        private void GUIVentanaPrincipal_Load(object sender, EventArgs e)
        {
            try
            {
                // Se establecen los permisos en la ventana principal segun los roles del usuario
                List<string[]> lstPermisos = new List<string[]>();
                lstPermisos = sistema.traerPermisosUsuario(usuario);

                if (!tslblUsuario.Text.Equals("admin"))
                {
                    habilitarFuncionalidades(lstPermisos);
                }

                // Se cargan los Datos de la pantalla principal
                DateTime ahora = DateTime.Now;
                tslblFecha.Text = ahora.ToLongDateString() + " " + ahora.ToLongTimeString();
                cargarReservasCheckInHoy();
                cargarInformacionVaria();

                CargarPlugIns();
                timer.Enabled = true;
                
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void refrescarDatosVentanaPrincipal()
        {
            DateTime ahora = DateTime.Now;

            tslblFecha.Text = ahora.ToShortDateString() + " " + ahora.ToLongTimeString();
            CANT_SEGS = CANT_SEGS+1;
            if (CANT_SEGS == SEGS_REFRESH_RESERVAS)
            {
                cargarReservasCheckInHoy();
                cargarInformacionVaria();
                CANT_SEGS = 0;
            }
            
        }

        private void cargarInformacionVaria()
        {
         try
         {
            lblCantClientes.Text = sistema.traerClientes().Count.ToString();
            lblCantidadHabitaciones.Text = sistema.traerHabitaciones(true).Count.ToString();
            lblCantHabLibresHoy.Text = (int.Parse(lblCantidadHabitaciones.Text) - sistema.traerNumeroDeHabitacionesOcupadas().Count).ToString();
            int cantHabCheckOutHoy=0;
            foreach(string[] res in sistema.obtenerReservas())
            {
                if (DateTime.Parse(res[2]).ToShortDateString().Equals(DateTime.Now.ToShortDateString()))
                    cantHabCheckOutHoy++;
            }
            lblCheckOutHoy.Text = cantHabCheckOutHoy.ToString();
         }catch(Exception ex)
         {
             throw ex;
         }
        }

        private void cargarReservasCheckInHoy()
        {
            try
            {
                
                foreach(ListViewItem lvi in lvReservas.Items)
                    lvReservas.Items.Remove(lvi);

                List<string[]> reservasHoy = sistema.obtenerReservasCheckInFecha(System.DateTime.Now, "Reservado");
                foreach (string[] reserva in reservasHoy)
                {
                    string[] cliente = sistema.traerCliente(int.Parse(reserva[4]));
                    ListViewItem item = lvReservas.Items.Add(reserva[0]);
                    item.SubItems.Add(cliente[1] + " " + cliente[2]);
                    item.SubItems.Add(reserva[5]);
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }

        }

        private void usuariosToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMUsuarios users = new ABMUsuarios();
            users.ShowDialog(this);

        }

        private void comodidadesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMComodidades comodities = new ABMComodidades();
            comodities.ShowDialog(this);
        }

        private void habitacionesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMHabitaciones habitaciones = new ABMHabitaciones();
            habitaciones.ShowDialog(this);
        }

        private void GUIVentanaPrincipal_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

        private void categoriasToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMCategorias categorias = new ABMCategorias();
            categorias.ShowDialog(this);

        }

        #region Metodos para cargar el Assembly

        public void CargarPlugIns()
        {
            string path = System.IO.Directory.GetCurrentDirectory() + "\\Plugins";
            string[] arch = System.IO.Directory.GetFiles(path);
            listaPaths = new List<string>();
            direccion = new List<string>();
            for (int i = 0; i < arch.Length; i++)
            {
                string ext = System.IO.Path.GetExtension(arch[i]);
                string name = System.IO.Path.GetFileName(arch[i]);
                if (ext.Equals(".dll"))
                {
                    listaPaths.Add(System.IO.Path.GetFileName(arch[i]));
                    direccion.Add(arch[i]);
                }
            }
            for (int i = 0; i < listaPaths.Count; i++)
            {
                if (listaPaths[i].ToString() != "PlugIns.dll")
                {
                    reflectionAssemblyString(path + "\\" + listaPaths[i]);
                }
            }
        }

        private void reflectionAssemblyString(string path)
        {

            assm = Assembly.LoadFrom(path);
            BindingFlags flags = (BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance | BindingFlags.DeclaredOnly);

            foreach (Type t in assm.GetTypes())
            {
                MethodInfo[] met = t.GetMethods(flags);

                Object instancia = Activator.CreateInstance(t);
                Object[] o = { };
                String resultado = (String)met[0].Invoke(instancia, o);

                ToolStripMenuItem menuItem = new ToolStripMenuItem();
                menuItem.Text = resultado;
                plugInsToolStripMenuItem.DropDownItems.Add(menuItem);
                menuItem.Click += new System.EventHandler(EventoReflection);
            }
         }
 
        private void EventoReflection(object sender, EventArgs e)
        {
            string opcion = ((ToolStripMenuItem)sender).Text;
            Type[] tipos = assm.GetTypes();
            foreach (Type tipo in tipos)
            {
                Type[] ifaces = tipo.GetInterfaces();
                foreach (Type ifaz in ifaces)
                {
                    if (ifaz.Name.Equals("IExtension"))
                    {
                        object obj = Activator.CreateInstance(tipo);
                        MethodInfo m = tipo.GetMethod("Ejecutar");
                        ParameterInfo[] parametros = m.GetParameters();
                        if (parametros.Length > 0)
                        {
                            object[] param = { opcion };
                            m.Invoke(obj, param);
                        }
                    }
                }
            }

        }

        #endregion

        private void plugInsToolStripMenuItem_Click(object sender, EventArgs e)
        {

        }

        private void consultaDeLogsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConsultaLogs cl = new ConsultaLogs();
            cl.Show();
        }

        private void clientesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMClientes clientes = new ABMClientes();
            clientes.ShowDialog(this);
        }

        private void precioDeHabitacionesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            PrecioHabitaciones ph = new PrecioHabitaciones();
            ph.ShowDialog(this);
        }

        private void ReservaToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Reservas reserva = new Reservas();
            reserva.ShowDialog(this);
        }

        public string getUsuarioLogueado()
        {
            //return "Administrador";
            return tslblUsuario.Text;
        }

        private void loToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Owner.Show();
            Log4Net.FactoryLogs.getLogInstance().info(sistema.obtenerIdUsuarioLogueado(), "Salida del Sistema.");
            this.Dispose();
        }

        private void Roles_Click(object sender, EventArgs e)
        {
            ABMRoles abmroles = new ABMRoles();
            abmroles.ShowDialog(this);
        }

        private void Permisos_Click(object sender, EventArgs e)
        {
            ABMPermisos permisos = new ABMPermisos();
            permisos.ShowDialog(this);
        }

        private void RolesPermisos_Click(object sender, EventArgs e)
        {
            RolesPermisos rp = new RolesPermisos();
            rp.ShowDialog();
        }

        private void UsuarioRoles_Click(object sender, EventArgs e)
        {
            UsuarioRoles ur = new UsuarioRoles();
            ur.ShowDialog();
        }

        private void paisesToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMPais abmpais = new ABMPais();
            abmpais.ShowDialog();
        }

        private void configToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ConfiguracionDeParametros config = new ConfiguracionDeParametros();
            config.ShowDialog();
        }

        private void impuestosToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ABMImpuestos abmImps = new ABMImpuestos();
            abmImps.ShowDialog();
        }

        public void habilitarFuncionalidades(List<string[]> lstPermisos)
        {
            ReservaToolStripMenuItem.Enabled = false;
            administraciónToolStripMenuItem.Enabled = false;
            consultaDeLogsToolStripMenuItem.Enabled = false;
            mantenimientoToolStripMenuItem.Enabled = false;
            UsuarioRoles.Enabled = false;
            foreach (string[] st in lstPermisos)
            {
                string s = st[1].Trim();
                if(s.Equals("Reservas"))  
                {
                    ReservaToolStripMenuItem.Enabled = true;
                }
                if (s.Equals("Administracion"))
                {
                    administraciónToolStripMenuItem.Enabled = true;
                }
                if (s.Equals("Consulta de Logs"))
                {
                    consultaDeLogsToolStripMenuItem.Enabled = true;
                }
                if (s.Equals("Mantenimiento"))
                {
                    mantenimientoToolStripMenuItem.Enabled = true;
                }
                if (s.Equals("Usuarios y Roles"))
                {
                    UsuarioRoles.Enabled = true;
                }
            }
        }

        private void cambiarPasswordToolStripMenuItem_Click(object sender, EventArgs e)
        {
            try
            {
                CambiarPasswordUsuario cpu = new CambiarPasswordUsuario(sistema.obtenerIdUsuarioLogueado());
                cpu.ShowDialog(this);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void lvReservas_DoubleClick(object sender, EventArgs e)
        {
            try
            {
                int NumReserva = int.Parse(lvReservas.SelectedItems[0].Text.Trim());
                int idHabitacion = int.Parse(lvReservas.SelectedItems[0].SubItems[2].Text.Trim());
                List<string[]> listaReservas = sistema.obtenerReservasCheckInFecha(DateTime.Now, "Reservado");
                int idCliente = 0;
                foreach (string[] res in listaReservas)
                {
                    if (int.Parse(res[0]) == NumReserva)
                        idCliente = int.Parse(res[4]);
                }
                if (idCliente != 0)
                {
                    Reservas reservas = new Reservas(NumReserva, idCliente, idHabitacion);
                    string[] cliente = sistema.traerCliente(idCliente);
                    reservas.setCliente(idCliente.ToString(), cliente[1], cliente[2]);
                    reservas.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
        }

        private void ReloadReservasCheckInHoy_Click(object sender, EventArgs e)
        {
            try
            {
                cargarReservasCheckInHoy();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
            this.refrescarDatosVentanaPrincipal();

        }


        
    }
}
